//
// Created by 张朝辉 on 2023/10/10.
//

#ifndef FA_LEARNING_NPDA_H
#define FA_LEARNING_NPDA_H

#include <set>
#include <map>
#include <stack>
#include <queue>
#include "tuple.h"

typedef struct {
    std::string q;           // 当前状态
    std::string w;           // 剩余的字符串
    std::stack<char> g;      // 栈中的内容
}ID;                         // instantaneous description，下推自动机的瞬时描述


class NPDA {
private:
    std::set<std::string> state_set;
    std::set<char> char_set;
    std::set<char> stack_charset;
    std::map<Tuple3,std::set<std::pair<std::string,std::string>>> rule_table;
    std::string start_state;
    char start_char;
    std::set<std::string> final_set;
    std::queue<ID> id_set;         // 瞬时状态队列，存储多个PDA的配置

    /*
     * 对某一配置进行特定的某个状态转换操作，并返回新的配置
     */
    auto get_newID(ID id,std::pair<std::string,std::string> t) -> ID;

    /*
     * 将某个PDA的配置（ID）状态转换后的配置存入瞬时状态队列末尾并返回true，若无法进行状态转换则返回false
     */
    auto state_transition(ID id) -> bool;
public:
    NPDA(std::set<std::string> state_set,std::set<char> char_set,std::set<char> stack_charset,std::map<Tuple3,std::set<std::pair<std::string,std::string>>> rule_table,
         std::string start_state,char start_char,std::set<std::string> final_set);

    /*
     * 判断NPDA能否以终态方式接收某个字符串
     */
    auto isAccept_str(std::string str) -> bool;

    /*
     * 打印NPDA的相关信息
     */
    auto description() -> void;
};


#endif //FA_LEARNING_NPDA_H
